package com.dg.dgrmi.handler;

import java.lang.reflect.*;

import com.dg.dgrmi.call.RemoteInstance;

/**
 * A dynamic proxy which delegates interface
 * calls to a ConnectionHandler
 *
 * @author lipe
 * @date   05/10/2006
 *
 * @see	   net.sf.lipermi.handler.CallHandler
 */
public class CallProxy implements InvocationHandler {

    private ConnectionHandler connectionHandler;

    /**
     * Create new CallProxy with a ConnectionHandler which will
     * transport invocations on this Proxy
     *
     * @param connectionHandler
     */
    public CallProxy(ConnectionHandler connectionHandler) {
        this.connectionHandler = connectionHandler;
    }

    /**
     * Delegates call to this proxy to it's ConnectionHandler
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws
            Throwable {
        return connectionHandler.remoteInvocation(proxy, method, args);
    }

    /**
     * Build a proxy to a {@see net.sf.lipermi.call.RemoteInstance RemoteInstance}
     * specifing how it could be reached (i.e., through a ConnectionHandler)
     *
     * @param  remoteInstance
     * @param  connectionHandler
     * @return dymamic proxy for RemoteInstance
     * @throws ClassNotFoundException
     */
    public static Object buildProxy(RemoteInstance remoteInstance,
                                    ConnectionHandler connectionHandler) throws
            ClassNotFoundException {
        Class<?> clazz = Class.forName(remoteInstance.getClassName());
        return Proxy.newProxyInstance(clazz.getClassLoader(),
                                      new Class[] {clazz},
                                      new CallProxy(connectionHandler));
    }
}
